package sjjg.op;


import java.util.*;

public class SJF {
    public static void main(String[] args) {
        /*初始化数据*/
        List<Process> processes = initProcess();
        /*存放一些预选的短作业*/
        List<Process> preProcess = new ArrayList<Process>(processes.size());
        /*记录作业完成的数量*/
        int flag=0;
        /*记录时间*/
        double time=processes.get(0).getToTime();
        /*保存结果信息*/
        List<Process> result= new ArrayList<>();
        /*初始化队列*/
        flag=updatePreQueue(processes, preProcess, flag, time);

        while (!preProcess.isEmpty()){
            Process process = preProcess.remove(0);
            double startTime=Math.max(process.getToTime(),time);
            process.setFinishTime(startTime+process.getServeTime());
            process.setrTime(process.getFinishTime()-process.getToTime());
            process.setWeightRTime(process.getrTime()/process.getServeTime());
            process.setAvgWeightRTIme(process.getWeightRTime()/processes.size());
            process.setWaitTime(process.getFinishTime()-process.getServeTime()-process.getToTime());
            result.add(process);
            time=process.getFinishTime();
            flag=updatePreQueue(processes,preProcess,flag,time);
        }
        /*遍历记录的结果*/
        System.out.println("进程        到达时间    服务时间    完成时间    周转时间    等待时间    带权周转时间 平均带权周转时间");
        for (Process process : result) {
            System.out.println("   "+process.getName()+"    "+
                    "   "+ String.format("%.2f",process.getToTime())+"   "+
                    "   "+ String.format("%.2f",process.getServeTime())+"    "+
                    "   "+ String.format("%.2f",process.getFinishTime())+"    "+
                    "   "+String.format("%.2f", process.getrTime())+"    "+
                    "   "+String.format("%.2f",process.getWaitTime())+"    "+
                    "   "+String.format("%.2f",process.getWeightRTime())+"    "+
                    "   "+String.format("%.2f", process.getAvgWeightRTIme())+"    ");
        }
    }

    private static int updatePreQueue(List<Process> processes, List<Process> preProcess, int flag, double time) {
        for(int i = flag; i< processes.size(); i++){
            Process process = processes.get(i);
            if(process.getToTime()<= time){
                preProcess.add(process);
                flag=flag+1;
            }else {
                break;
            }
        }
        preProcess.sort((p1,p2)->{
            return (int) (p1.getServeTime()-p2.getServeTime());
        });
        return flag;
    }

    private static List<Process> initProcess() {
        List<Process> Processs = new ArrayList<>();
        Process a = new Process("a", 1,7);
        Processs.add(a);
        Process b = new Process("b", 3,3);
        Processs.add(b);
        Process c = new Process("c", 6,2);
        Processs.add(c);
        Process d = new Process("d", 7,10);
        Processs.add(d);
        Process e = new Process("e", 9,8);
        Processs.add(e);
        Processs.sort(( Process1, Process2)->{
            return (int) (Process1.getToTime()-Process2.getToTime());
        });
        return Processs;
    }
}
